<?php

namespace app\api\controller;

use app\admin\model\Node as NodeModel;
use app\admin\model\NodeDetail as NodeDetailModel;
use app\admin\model\Product as ProductModel;
use app\common\controller\Api;
use fast\Random;
use think\Db;
use think\Exception;

/**
 * 产品接口
 */
class Product extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = '*';

    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new ProductModel();
    }

    /**
     * 创建产品
     */
    public function create()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }

        //接收并验证数据
        $row = $this->request->post('', '', 'trim,xss_clean');

        $rule = [
            'name|产品名称' => 'require',
            'is_template|是否使用模板' => 'require|in:0,1',//0不使用1使用
            'template_sn|模板编号' => 'requireIf:is_template,1'
        ];
        $validate = $this->validate($row, $rule);
        if ($validate !== true) {
            $this->error($validate);
        }

        if ($row['is_template'] == 1) {
            $template = Db::name('template')->where('sn', $row['template_sn'])->find();
            if (!$template) {
                $this->error('当前模板不存在');
            }
            if ($template['user_id'] != $this->auth->id) {
                $order = Db::name('order')->where(['template_id' => $template['id'], 'user_id' => $this->auth->id, 'pay_state' => 1])->find();
                if (!$order) {
                    $this->error('该模板不在我的模板库中');
                }
            }
        }

        Db::startTrans();
        try {
            // 添加产品
            $sn = Random::alnum(13);
            $this->model->name = $row['name'];
            $this->model->template_id = $row['is_template'] == 1 ? $template['id'] : 0;
            $this->model->user_id = $this->auth->id;
            $this->model->sn = $sn;
            $this->model->company_id = $this->auth->company_id;
            $this->model->save();

            //添加节点
            $nodeModel = new NodeModel();
            if ($row['is_template'] == 1) {
                //添加节点
                $list = [];
                $snapshot = json_decode($template['snapshot'], true);
                foreach ($snapshot as $k => $v) {
                    $list[$k]['level'] = $v['level'];
                    $list[$k]['user_id'] = $this->auth->id;
                    $list[$k]['name'] = $v['topic'];
                    $list[$k]['product_id'] = $this->model->id;
                    $list[$k]['is_factor'] = $v['is_factor'];
                    $list[$k]['factor_id'] = $v['factor_id'];
                    $list[$k]['node_type'] = $v['node_type'];
                    $list[$k]['origin_id'] = $v['id'];
                    $list[$k]['origin_path'] = $v['path'];
                    $list[$k]['origin_pid'] = $v['pid'];
                    $list[$k]['from_template'] = $v['from_template'];
                    $list[$k]['rank'] = $v['rank'];
                    $list[$k]['template_mark'] = $v['template_mark'];
                }

                $new_data = $nodeModel->saveAll($list);

                foreach ($new_data as $v) {
                    $reflect[$v->origin_id] = $v->id;
                }

                foreach ($new_data as $v) {
                    if ($v->origin_path == '-') {
                        $v->pid = 0;
                        $v->path = '-';
                    } else {
                        $v->pid = $reflect[$v->origin_pid];
                        $v->path = $this->reflect($reflect, $v->origin_path);
                    }
                    $v->save();
                }

                //添加节点输入输出类型类别
                $detail_list = [];
                $node_detail = json_decode($template['node_detail'], true);
                foreach ($node_detail as $k => $v) {
                    $detail_list[$k]['user_id'] = $this->auth->id;
                    $detail_list[$k]['product_id'] = $this->model->id;
                    $detail_list[$k]['io_type_id'] = $v['io_type_id'];
                    $detail_list[$k]['io_category_id'] = $v['io_category_id'];
                    $detail_list[$k]['type'] = $v['type'];
                    $detail_list[$k]['io_value'] = NULL;
                    $detail_list[$k]['copy_node_id'] = $v['node_id'];
                    $detail_list[$k]['copy_id'] = $v['id'];
                }

                $nodeDetailModel = new NodeDetailModel;
                $new_data = $nodeDetailModel->saveAll($detail_list);

                foreach ($new_data as $v) {
                    $new_item = $nodeModel->where('origin_id', $v->copy_node_id)->order('id', 'desc')->find();
                    $v->node_id = $new_item->id;
                    $v->save();
                }

            } else {
                $nodeModel->pid = 0;
                $nodeModel->product_id = $this->model->id;
                $nodeModel->name = $row['name'];
                $nodeModel->level = 1;
                $nodeModel->path = '-';
                $nodeModel->user_id = $this->auth->id;
                $nodeModel->save();
            }

            Db::commit();

        } catch (Exception $e) {
            Db::rollback();
            $this->error('添加产品失败: ' . $e->getMessage());
        }

        $this->success('添加产品成功', ['sn' => $sn]);

    }

    protected function reflect($reflect, $path)
    {
        $item = [];
        $arr = explode('-', $path);
        foreach ($arr as $v) {
            if ($v) {
                $item[] = $reflect[$v];
            } else {
                $item[] = $v;
            }
        }
        return implode('-', $item);
    }

    /**
     * 编辑产品
     */
    public function edit()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }

        //接收并验证数据
        $row = $this->request->post('', '', 'trim,xss_clean');

        $rule = [
            'sn|产品编号' => 'require',
            'name|产品名称' => 'require',
        ];
        $validate = $this->validate($row, $rule);
        if ($validate !== true) {
            $this->error($validate);
        }

        // 产品描述
        $desc = $this->request->post('desc', '', 'trim,xss_clean');

        $product = $this->model->where('sn', $row['sn'])->find();

        if (!$product) {
            $this->error('产品不存在');
        }

        if ($product->user_id != $this->auth->id) {
            $this->error('你不是产品拥有者，不能编辑');
        }

        try {
            $product->name = $row['name'];
            $product->description = $desc;
            $product->save();
        } catch (Exception $e) {
            $this->error('编辑产品失败: ' . $e->getMessage());
        }

        $this->success('编辑产品成功');
    }

    /**
     * 产品详情
     */
    public function detail()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }

        //接收并验证数据
        $row = $this->request->post('', '', 'trim,xss_clean');

        $rule = [
            'sn|产品编号' => 'require',
        ];
        $validate = $this->validate($row, $rule);
        if ($validate !== true) {
            $this->error($validate);
        }

        $product = $this->model->where('sn', $row['sn'])->find();

        if (!$product) {
            $this->error('产品不存在');
        }

        if ($product->user_id != $this->auth->id) {
            $this->error('你不是产品拥有者，不能查看');
        }

        $this->success('获取产品详情成功', $product);
    }

    /**
     * 产品列表
     */
    public function list()
    {

        $where['user_id'] = ['=', $this->auth->id];
        $name = $this->request->param('name', '');
        if ($name) {
            $where['name|sn'] = ['like', '%' . $name . '%'];
        }
        $list = $this->model->where($where)->order('createtime', 'desc')->paginate()->each(function ($item) {
            $item->append(['last_edit_time']);
        });
        $this->success('获取产品列表成功', $list);
    }

    /**
     * 产品统计信息
     */
    public function statistic()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }

        //接收并验证数据
        $row = $this->request->post('', '', 'trim,xss_clean');

        $rule = [
            'sn|产品编号' => 'require',
        ];
        $validate = $this->validate($row, $rule);
        if ($validate !== true) {
            $this->error($validate);
        }

        $product = $this->model->where('sn', $row['sn'])->find();

        if (!$product) {
            $this->error('产品不存在');
        }

        $data = Db::name('node_detail')
            ->alias('a')
            ->join('io_category b', 'b.id = a.io_category_id')
            ->distinct(true)
            ->field('b.name,b.type')
            ->where('a.product_id', $product->id)
            ->select();

        $energy = [];
        $waste = [];
        foreach ($data as $v) {
            if ($v['type'] == 0) {
                $energy[] = $v['name'];
            } else {
                $waste[] = $v['name'];
            }
        }

        $tree = NodeModel::field('convert(id,char) id,convert(pid,char) pid,name as topic,convert(is_factor,char) is_factor,template_mark,`rank`')->where('product_id', $product->id)
            ->where(function($query) {
                $query->where('rank', 1);
                $query->whereOr(function($query1) {
                    $query1->where('rank', 2);
                    $query1->where('origin_path', '-');
                });
            })
            ->select()->toArray();
        $tree = $this->buildTree($tree);

        $this->success('获取产品统计信息成功', ['node_tree' => $tree, 'energy' => $energy, 'waste' => $waste]);
    }

    /**
     * 回收站
     */
    public function recycleBin()
    {
        $limit_time = strtotime('-2 days',strtotime(date('Y-m-d 00:00:00')));

        //删除15天之前的数据
        ProductModel::onlyTrashed()->where('user_id',  $this->auth->id)
            ->where('deletetime','<=',$limit_time)
            ->delete();


        $list = ProductModel::onlyTrashed()->where('user_id', $this->auth->id)
            ->field('id,sn,name,deletetime')
            ->order('deletetime', 'desc')
            ->paginate();

        if (!$list->isEmpty()) {
            $list->each(function ($item, $key) {
                $item->append(['delete_date_time']);
            });
        }

        $this->success('获取产品列表成功', $list);
    }

    /**
     * 恢复产品
     */
    public function restore()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }

        //接收并验证数据
        $row = $this->request->post('', '', 'trim,xss_clean');

        $rule = [
            'sn|产品编号' => 'require',
        ];
        $validate = $this->validate($row, $rule);
        if ($validate !== true) {
            $this->error($validate);
        }

        $product = ProductModel::onlyTrashed()->where('sn', $row['sn'])->find();
        if (!$product) {
            $this->error('产品不存在');
        }
        if ($product->user_id != $this->auth->id) {
            $this->error('你不是产品拥有者，不能恢复');
        }
        try {
            $this->model->restore(['id' => $product->id]);
            $this->success('恢复产品成功');
        } catch (Exception $e) {
            $this->error('恢复产品失败: ' . $e->getMessage());
        }

    }

    public function destroy()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }

        //接收并验证数据
        $row = $this->request->post('', '', 'trim,xss_clean');

        $rule = [
            'sn|产品编号' => 'require',
        ];
        $validate = $this->validate($row, $rule);
        if ($validate !== true) {
            $this->error($validate);
        }

        $product = ProductModel::onlyTrashed()->where('sn', $row['sn'])->find();
        if (!$product) {
            $this->error('产品不存在');
        }
        if ($product->user_id != $this->auth->id) {
            $this->error('你不是产品拥有者，不能删除');
        }
        try {
            $product->delete(true);
            $this->success('删除产品成功');
        } catch (Exception $e) {
            $this->error('删除产品失败: ' . $e->getMessage());
        }
    }

    /**
     * 删除产品
     */
    public function delete()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }

        //接收并验证数据
        $row = $this->request->post('', '', 'trim,xss_clean');

        $rule = [
            'sn|产品编号' => 'require',
        ];
        $validate = $this->validate($row, $rule);
        if ($validate !== true) {
            $this->error($validate);
        }

        $product = $this->model->where('sn', $row['sn'])->find();

        if (!$product) {
            $this->error('产品不存在');
        }

        if ($product->user_id != $this->auth->id) {
            $this->error('你不是产品拥有者，不能删除');
        }

        try {
            $product->delete();
        } catch (Exception $e) {
            $this->error('删除产品失败: ' . $e->getMessage());
        }

        $this->success('删除产品成功');
    }

}
